/*
visqrt
Copyright (C) 2010  Bhupendra Aole

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
*/
/*
 * File: Object3D.java
 * Author: Bhupendra Aole
 * Date: Aug 27, 2010: 
 * 
 * Revisions:
 * ----------
 */

package aole.object;

import aole.math.Color3;
import aole.math.Vec3;
import aole.plugin.VQObject;
import aole.texture.PerlinNoise;
import aole.texture.Texture3;

public abstract class Renderable implements VQObject {
	public static final int TEXTURE_NONE = 0;
	public static final int TEXTURE_TURBULENCE = 1;
	public static final int TEXTURE_MARBLE = 2;

	public static final int MAPPING_NONE = 0;
	public static final int MAPPING_BUMP = 1;

	public static final int ILLUM_LAMBERT = 0;
	public static final int ILLUM_PHONG = 1;
	public static final int ILLUM_BLINN = 2;

	// color of the object, randomized
	protected Color3 color = Color3.getRandom();

	// texture
	protected Texture3 texture;

	// lambertian coefficient
	public float lamCoef = 1f;
	// reflection coefficient
	public float reflCoef = 0f;
	// refraction coefficient
	public float refrCoef = 0f;

	public float specvalue = 1f;
	public float specpower = 100;
	// refraction
	// index of refraction
	public float ior = 1f;

	public int mapping = MAPPING_NONE;
	public int illumination = ILLUM_LAMBERT;

	public float level_bump = .3f;

	public abstract float calcIntersection (Vec3 p, Vec3 d);

	public abstract Vec3 getNormal (Vec3 ip);

	public void setColor (float r, float g, float b) {
		color.set(r, g, b);
	}

	public void setColor (Color3 c) {
		color = c;
	}

	public Color3 getColor (Vec3 ip) {
		if (texture == null)
			return color;
		return texture.getColor(ip);
		// TODO: replace with better architectures
		/*
		float noiseCoef = .5f;
				if (texture == TEXTURE_TURBULENCE) {
					for (int level = 1; level < 10; level++) {
						noiseCoef += (1.0f / level)
								* Math.abs(Perlin.noise(level * ip.x, level * ip.y,
										level * ip.z));
					}

					return new Color3(Color3.add(color.getScaled(noiseCoef), color2
							.getScaled(1f - noiseCoef)));
				} else if (texture == TEXTURE_MARBLE) {
					for (int level = 1; level < 10; level++) {
						noiseCoef += (1.0f / level)
								* Math.abs(Perlin.noise(level * ip.x, level * ip.y,
										level * ip.z));
					}
					noiseCoef = (float) (0.5f * Math.sin((ip.x + ip.y) * 0.2f
							+ noiseCoef) + 0.5f);
					return new Color3(Color3.add(color.getScaled(noiseCoef), color2
							.getScaled(1f - noiseCoef)));
				} else
					return color;
					*/
	}

	public void setTexture (String s) {
		/*if (s.equals("turbulence"))
			texture = TEXTURE_TURBULENCE;
		else if (s.equals("marble"))
			texture = TEXTURE_MARBLE;
		else*/if (s.equals("noise"))
			texture = new PerlinNoise();
	}

	public void readmapping (String s) {
		if (s.equals("bump"))
			mapping = MAPPING_BUMP;
	}

	public void setIllumination (String s) {
		if (s.equals("phong"))
			illumination = ILLUM_PHONG;
		else if (s.equals("blinn"))
			illumination = ILLUM_BLINN;
	}

	public void setColor (String s) {
		color.read(s);
	}

	public void setReflect (float r) {
		reflCoef = r;
	}

	public void setRefract (float r) {
		refrCoef = r;
	}

	public void setIor (float i) {
		ior = i;
	}
}
